package com.candoit.webapps.pricing.controllers;

import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.component.html.HtmlPanelGroup;

import com.candoit.webapps.pricing.model.Categoria;
import com.candoit.webapps.pricing.model.CentroCostos;
import com.candoit.webapps.pricing.model.CentroCostosCriterio;
import com.candoit.webapps.pricing.model.ConsumoPapelMes;
import com.candoit.webapps.pricing.model.CriterioDistribucion;
import com.candoit.webapps.pricing.model.CuentaMes;
import com.candoit.webapps.pricing.model.Maquina;
import com.candoit.webapps.pricing.model.OrdenTrabajo;
import com.candoit.webapps.pricing.model.OrdenTrabajoMes;
import com.candoit.webapps.pricing.util.QueryUtil;

@ManagedBean(name = "distribucionCtrl")
@ViewScoped
public class DistribucionCentroCostosController extends AbstractController {
	private HtmlPanelGroup panelGroup;
	private List<CuentaMes> cuentas;
	private List<CentroCostos> centros;
	private Map<Integer, Double> mapDistribucion = null;
	

	public HtmlPanelGroup getPanelGroup() {
		if (panelGroup == null){
			this.loadLists();
			this.fiilPanelGroup();
		}
		return panelGroup;
	}

	public void setPanelGroup(HtmlPanelGroup panelGroup) {
		this.panelGroup = panelGroup;
	}
	
	public List<CuentaMes> getCuentas() {
		return cuentas;
	}

	public void setCuentas(List<CuentaMes> cuentas) {
		this.cuentas = cuentas;
	}
	
	public List<CentroCostos> getCentros() {
		return centros;
	}

	public void setCentros(List<CentroCostos> centros) {
		this.centros = centros;
	}
	
	public Map<Integer, Double> getMapDistribucion() {
		return mapDistribucion;
	}

	public void setMapDistribucion(Map<Integer, Double> mapDistribucion) {
		this.mapDistribucion = mapDistribucion;
	}

	private void fiilPanelGroup(){
		mapDistribucion = new HashMap<Integer,Double>();
		HtmlPanelGrid panelGrid = fillPanelGridAllCC();
		HtmlPanelGrid panelGridParaProductivos = fillPanelParaProductivos();
		HtmlPanelGrid panelGridSinAsignar = fillPanelGridSinAsignar();
		HtmlOutputText breakLine = new HtmlOutputText();
		breakLine.setValue(""); 
		panelGroup = new HtmlPanelGroup();
        panelGroup.getChildren().add(panelGrid);
        panelGroup.getChildren().add(breakLine);
        panelGroup.getChildren().add(panelGridParaProductivos);
        panelGroup.getChildren().add(panelGridSinAsignar);
	}
	 
	private void loadLists(){
		Calendar cal = new GregorianCalendar();
		Date fechaActual = new Date();
		cal.setTime(fechaActual);
		Integer mesActual = cal.get(Calendar.MONTH);
		cuentas = QueryUtil.getInstance().getCuentasByMesExceptsMO();
		centros = QueryUtil.getInstance().getCentrosListOrderByCatgory();
	}
	
	private HtmlPanelGrid fillPanelGridAllCC(){
		HtmlPanelGrid panelGrid = new HtmlPanelGrid();
		DecimalFormat twoDForm = new DecimalFormat("#.##");
		panelGrid.getChildren().clear();
		panelGrid.setColumnClasses("headindistribucion");
		panelGrid.setRowClasses("headindistribucion");
        panelGrid.setColumns(2 + centros.size());
        panelGrid.setColumnClasses("heading");
        panelGrid.setStyleClass("panelgroupdistribucion");
        HtmlOutputText headerCuenta = new HtmlOutputText();
        headerCuenta.setValue("Cuenta");
        panelGrid.getChildren().add(headerCuenta);
        HtmlOutputText totalMes = new HtmlOutputText();
        totalMes.setValue("Total");
        panelGrid.getChildren().add(totalMes);
        for(CentroCostos centro : centros){
        	HtmlOutputText centroOutput = new HtmlOutputText();
        	centroOutput.setValue(centro.getNombre());
        	panelGrid.getChildren().add(centroOutput);
        }
        for(CuentaMes cuenta : cuentas){
            HtmlOutputText cuentaNombre = new HtmlOutputText();
            cuentaNombre.setValue(cuenta.getCuentaMesFK().getCuenta().getDescripcion());
            panelGrid.getChildren().add(cuentaNombre);
            HtmlOutputText totalCuenta = new HtmlOutputText();
            totalCuenta.setValue(cuenta.getCosto());
            panelGrid.getChildren().add(totalCuenta);
            for (CentroCostos centro : centros){
            	if (cuenta.getCuentaMesFK().getCuenta().getCriterio().getId() == CriterioDistribucion.DIRECTA_CODE ){
                    if (cuenta.getCuentaMesFK().getCuenta().getCentro().getId() == centro.getId() ){	
            			HtmlOutputText directaCuenta = new HtmlOutputText();
                    	directaCuenta.setValue(cuenta.getCosto());
                    	panelGrid.getChildren().add(directaCuenta);
                    	if (!mapDistribucion.containsKey(centro.getId())){
                    		mapDistribucion.put(centro.getId(), cuenta.getCosto());
                    	}else{
                    		mapDistribucion.put(centro.getId(), mapDistribucion.get(centro.getId()) + cuenta.getCosto());
                    	}
                    }else{
                    	HtmlOutputText directaCuenta = new HtmlOutputText();
                    	directaCuenta.setValue(0.00d);
                    	panelGrid.getChildren().add(directaCuenta);
                    }
            	}else{
            		CentroCostosCriterio centroCriterio = QueryUtil.getInstance().getCentroCostosCriterioObject(centro, cuenta.getCuentaMesFK().getCuenta().getCriterio());
            		HtmlOutputText criterioCuenta = new HtmlOutputText();
            		Double totalAsignado = QueryUtil.getInstance().getTotalAsignadoCriterio(cuenta.getCuentaMesFK().getCuenta().getCriterio());
            		Double criterioPorc = 0.00d;
            		if (centroCriterio != null){
            			criterioPorc = centroCriterio.getCantidad()/totalAsignado;
            		}	
            		Double criterio = cuenta.getCosto() *criterioPorc;
            		if (!mapDistribucion.containsKey(centro.getId())){
                		mapDistribucion.put(centro.getId(), criterio);
                	}else{
                		mapDistribucion.put(centro.getId(), mapDistribucion.get(centro.getId()) + criterio);
                	}
            		criterioCuenta.setValue(twoDForm.format(criterio));
            		panelGrid.getChildren().add(criterioCuenta);
            	}
            }
        }
        
        HtmlOutputText totales = new HtmlOutputText();
        totales.setValue("Totales");
        panelGrid.getChildren().add(totales);
        HtmlOutputText brekline = new HtmlOutputText();
        brekline.setValue("");
        panelGrid.getChildren().add(brekline);
        
        for(CentroCostos centro : centros){
            HtmlOutputText totalesCentro = new HtmlOutputText();
            totalesCentro.setValue(twoDForm.format(mapDistribucion.get(centro.getId())));
            panelGrid.getChildren().add(totalesCentro);
        }
        
        
		return panelGrid;
	}
	
	private HtmlPanelGrid fillPanelParaProductivos(){
		HtmlPanelGrid panelGrid = new HtmlPanelGrid();
		List<CentroCostos> paraProductivos = QueryUtil.getInstance().getCentroCostosByCategoria(Categoria.SERVICES_CODE);
		List<CentroCostos> industriales = QueryUtil.getInstance().getCentroCostosByCategoria(Categoria.PRODUCTION_CODE);
		DecimalFormat twoDForm = new DecimalFormat("#.##");
		panelGrid.getChildren().clear();
		panelGrid.setColumnClasses("headindistribucion");
		panelGrid.setRowClasses("headindistribucion");
        panelGrid.setColumns(2 + industriales.size());
        panelGrid.setColumnClasses("heading");
        panelGrid.setStyleClass("panelgroupdistribucion");
        HtmlOutputText headerCuenta = new HtmlOutputText();
        headerCuenta.setValue("Cuenta");
        panelGrid.getChildren().add(headerCuenta);
        HtmlOutputText totalMes = new HtmlOutputText();
        totalMes.setValue("Total");
        panelGrid.getChildren().add(totalMes);
        
        
        for(CentroCostos industrial : industriales){
        	 HtmlOutputText centro = new HtmlOutputText();
        	 centro.setValue(industrial.getNombre());
             panelGrid.getChildren().add(centro);
        }
        
		
        for (CentroCostos paraProd : paraProductivos){
			 HtmlOutputText paraProdOuput = new HtmlOutputText();
			 paraProdOuput.setValue(paraProd.getNombre());
			 panelGrid.getChildren().add(paraProdOuput);
			 HtmlOutputText totalParaProd= new HtmlOutputText();
			 totalParaProd.setValue(twoDForm.format(mapDistribucion.get(paraProd.getId())));
			 panelGrid.getChildren().add(totalParaProd);
        	  for(CentroCostos industrial : industriales){
        		 Maquina maquina = QueryUtil.getInstance().getMaquinaByCentroCostos(industrial);  
        		 if (paraProd.getMaquinas().contains(maquina)){
        			 Double output = mapDistribucion.get(paraProd.getId()) / paraProd.getMaquinas().size();
        			 HtmlOutputText distribucion = new HtmlOutputText();
        			 distribucion.setValue(twoDForm.format(output));
        			 panelGrid.getChildren().add(distribucion);
        			 mapDistribucion.put(industrial.getId(), mapDistribucion.get(industrial.getId()) +  output);
        		}else{
        			HtmlOutputText distribucion = new HtmlOutputText();
        			distribucion.setValue(twoDForm.format(0.00d));
        			panelGrid.getChildren().add(distribucion);
        		 }
        	  }	 
        }
        
        HtmlOutputText totalesReDist = new HtmlOutputText();
        totalesReDist.setValue("Totales");
        panelGrid.getChildren().add(totalesReDist);
        HtmlOutputText breklineReDist = new HtmlOutputText();
        breklineReDist.setValue("");
        panelGrid.getChildren().add(breklineReDist);
        
        for(CentroCostos centro : industriales){
        	 HtmlOutputText totalesCentro = new HtmlOutputText();
        	 totalesCentro.setValue(twoDForm.format(mapDistribucion.get(centro.getId())));
        	panelGrid.getChildren().add(totalesCentro);
        }

		return panelGrid;
	}
	
	private HtmlPanelGrid fillPanelGridSinAsignar(){
		DecimalFormat twoDForm = new DecimalFormat("#.##");
		HtmlPanelGrid panelGrid = new HtmlPanelGrid();
		List<CentroCostos> centros = QueryUtil.getInstance().getCentroCostosByCategoria(Categoria.SIN_ASIGNAR_CODE);
		panelGrid.getChildren().clear();
		panelGrid.setColumnClasses("headindistribucion");
		panelGrid.setRowClasses("headindistribucion");
        panelGrid.setColumns(4);
        panelGrid.setColumnClasses("heading");
        HtmlOutputText totalesReDist = new HtmlOutputText();
        totalesReDist.setValue("Gastos sin asignar");
        panelGrid.getChildren().add(totalesReDist);
        HtmlOutputText total = new HtmlOutputText();
        total.setValue("Total");
        panelGrid.getChildren().add(total);
        HtmlOutputText cabeceraIndustrial = new HtmlOutputText();
        cabeceraIndustrial.setValue("Indust");
        panelGrid.getChildren().add(cabeceraIndustrial);
        HtmlOutputText cabeceraArtesanal = new HtmlOutputText();
        cabeceraArtesanal.setValue("Artes");
        panelGrid.getChildren().add(cabeceraArtesanal);
        
		 Calendar cal = new GregorianCalendar();
		 Date fechaActual = new Date();
		 cal.setTime(fechaActual);
		 Integer mesActual = cal.get(Calendar.MONTH);
		 
		 List<ConsumoPapelMes> consumoPapel = QueryUtil.getInstance().getConsumoPapelMes();
		 List<OrdenTrabajo> ots = QueryUtil.getInstance().getOrdenesTrabajo();
		 Double totalKg = QueryUtil.getInstance().getTotalKgConsumoPapel(mesActual);
		 Long totalOt = QueryUtil.getInstance().getTotalOrdenTrabajo(mesActual);
        
        for (CentroCostos centro : centros){
        	HtmlOutputText centroOutput = new HtmlOutputText();
        	centroOutput.setValue(centro.getNombre());
       	 	panelGrid.getChildren().add(centroOutput);
       		HtmlOutputText totalesCentro = new HtmlOutputText();
       	 	totalesCentro.setValue(twoDForm.format(mapDistribucion.get(centro.getId())));
       	 	panelGrid.getChildren().add(totalesCentro);
       	 	if (centro.getNombre().equals("EXPEDICION")){
       	 		for (ConsumoPapelMes c : consumoPapel){
       	 			 Double percKilos = c.getKilos() / totalKg;
       	 			 Double percOt = c.getOrden().getCantidad() / totalOt.doubleValue();
       	 			 Double mixConsumoPapel = c.getMixConsumoPapel() * percKilos;
       	 			 Double mixOt = c.getMixOrdenesTrabajoEmitidas() * percOt;
       	 			 Double sumaMix = mixOt + mixConsumoPapel;
       	 			 Double output  = mapDistribucion.get(centro.getId()) * sumaMix;
       	 			 HtmlOutputText consumoExp = new HtmlOutputText();
       	 			 consumoExp.setValue(twoDForm.format(output));
       	       	 	 panelGrid.getChildren().add(consumoExp);
       	 		}
       	 	}else{
       	 		for (OrdenTrabajo ot : ots){
       	 			Double perc = ot.getCantidad() / totalOt.doubleValue();
       	 			Double output = mapDistribucion.get(centro.getId()) * perc;
      	 			HtmlOutputText ordenTrabajo = new HtmlOutputText();
      	 			ordenTrabajo.setValue(twoDForm.format(output));
      	       	 	panelGrid.getChildren().add(ordenTrabajo);
       	 		}
       	 	}
        }
		return panelGrid;
	}
	
	
}
